package Threadprojects.pro2_knn.grounp2;

import Threadprojects.pro2_knn.bean.BankMarketing;
import Threadprojects.pro2_knn.bean.Distance;
import Threadprojects.pro2_knn.bean.Sample;
import Threadprojects.pro2_knn.util.DistanceCalculator;

import java.util.*;
import java.util.concurrent.*;

public class PGKClassfier {
    int k;//临近的有几个
    int numThreads;//线程数

    Boolean parallerlSort;//是否并行排序

    List<BankMarketing> dataset;//训练集
     ThreadPoolExecutor tpe =new ThreadPoolExecutor(
             (int) (numThreads*1.5),
             16,
             20,
             TimeUnit.SECONDS,
             new ArrayBlockingQueue<>(2059),
             Executors.defaultThreadFactory(),
             new ThreadPoolExecutor.AbortPolicy()
     );

    public PGKClassfier(int k, int numThreads, Boolean parallerlSort, List<BankMarketing> dataset) {
        this.k = k;
        this.numThreads = numThreads;
        this.parallerlSort = parallerlSort;
        this.dataset = dataset;

    }
    public String classfier(Sample example){
        CountDownLatch latch=new CountDownLatch(numThreads);

        Distance[] distances=new Distance[dataset.size()];

        int length= dataset.size()/numThreads;
        int startIndex=0;
        int endIndex=length;
        ArrayList<Thread> list = new ArrayList<>();
        for (int i = 0; i < numThreads; i++) {
            GrounpDistanceTask task = new GrounpDistanceTask(distances, startIndex, endIndex, dataset, example,  latch);
//            Thread t=new Thread(task);
//            t.start();
//            list.add(t);
            tpe.submit(task);
            startIndex=endIndex;
            endIndex=i==numThreads-2? dataset.size() : endIndex+length;
           // System.out.println("第"+i+"个线程的计算范围是"+startIndex+"到"+endIndex);
        }
//        for (Thread t : list) {
//            try {
//                t.join();
//            } catch (InterruptedException e) {
//                throw new RuntimeException(e);
//            }
//        }

        try {
            latch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        if (parallerlSort){
            Arrays.parallelSort(distances);
        }else {
            Arrays.sort(distances);
        }

        Map<String, Integer> rs = new HashMap<>();

        for (int i = 0; i < k; i++) {
            Sample sample = dataset.get(distances[i].getIndex());
            String tag = sample.getTag();
//            高级用法,意思是当没有tag的时候设为1,有tag则累加
            rs.merge(tag,1, Integer::sum);
        }
        //高级排序方法获取最大值的

        // 判断 rs 是否为空或者没有任何条目
        if (rs.isEmpty()) {
            throw new RuntimeException("无法找到分类结果，HashMap为空或者没有条目。");
        }

        // 获取最大值的标签

        return Collections.max(rs.entrySet(), Map.Entry.comparingByValue()).getKey();


    }
}
